package com.zjw.zy.utils.taskpool;

import android.os.Handler;
import android.os.Looper;


import com.zjw.zy.smi.JustReturnIt;
import com.zjw.zy.smi.JustWithIt;

import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池
 */
public final class TaskPool {

    private static final String TAG = "TaskPool";

    /**
     * 免代码逻辑导致的宕机，控制最大线程数
     */
    private static final int MAX_CONCURRENT_THREAD_COUNT = 20;
    private static final int MAX_CONCURRENT_CORE_THREAD_COUNT = 0;


    private final Executor mTaskPool;

    private final Handler mHandler = new Handler(Looper.getMainLooper());


    private TaskPool(Executor pool) {
        mTaskPool = pool;
    }

    private static final class SequentialHolder {
        public static final TaskPool INSTANCE = new TaskPool(Executors.newSingleThreadExecutor());
    }

    private static final class ConcurrentHolder {
        public static final TaskPool INSTANCE = new TaskPool(new ThreadPoolExecutor(
                MAX_CONCURRENT_CORE_THREAD_COUNT,
                MAX_CONCURRENT_THREAD_COUNT,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<>(),
                new ThreadPoolExecutor.DiscardPolicy()));

    }

    private static final class GraphicHolder {
        public static final TaskPool INSTANCE = new TaskPool(GraphicExecutor.get());
    }

    private static final class MainHolder {
        public static final TaskPool INSTANCE = new TaskPool(MainExecutor.get());
    }

    private static final class BackGroundHolder {
        public static final TaskPool INSTANCE = new TaskPool(BackGroundExecutor.get());
    }

    private static final class VoiceReceiveHolder {
        public static final TaskPool INSTANCE = new TaskPool(Executors.newSingleThreadExecutor());
    }

    private static final class VoiceSenderHolder {
        public static final TaskPool INSTANCE = new TaskPool(Executors.newSingleThreadExecutor());
    }


    /**
     * 创建一个串行的单线程的任务池，单例
     */
    public static TaskPool sequential() {
        return SequentialHolder.INSTANCE;
    }

    /**
     * 一个带并发的抢占式任务池，单例
     */
    public static TaskPool concurrent() {
        return ConcurrentHolder.INSTANCE;
    }

    /**
     * 一个专门在UI层绘制的任务池，单例
     */
    public static TaskPool graphic() {
        return GraphicHolder.INSTANCE;
    }

    /**
     * 一个专门在主线程执行的任务池，单例
     */
    public static TaskPool main() {
        return MainHolder.INSTANCE;
    }

    /**
     * 调度BackGround执行的任务池，单例
     */
    public static TaskPool backGround() {
        return BackGroundHolder.INSTANCE;
    }

    /**
     * 语音通话专用线程池
     */
    public static TaskPool voiceReceive() {
        return VoiceReceiveHolder.INSTANCE;
    }

    /**
     * 语音通话专用线程池
     */
    public static TaskPool voiceSend() {
        return VoiceSenderHolder.INSTANCE;
    }

    /**
     * 创建一个自定义的任务池，非单例，没调用一次该函数，均创建一个新的任务池
     *
     * @param pool:自定义线程Executor
     */
    public static TaskPool custom(Executor pool) {
        return new TaskPool(pool);
    }

    public static Holder holder() {
        return new Holder();
    }

    /**
     * 提交任务
     *
     * @param task:提交的任务
     */
    public void post(Runnable task) {
        mTaskPool.execute(task);
    }

    /**
     * 提交任务
     *
     * @param task:提交的任务
     * @param delayMillis:延迟执行(毫秒)
     */
    public void postDelayed(Runnable task, long delayMillis) {
        mHandler.postDelayed(() -> {
            post(task);
        }, delayMillis);
    }

    /**
     * 提交任务
     *
     * @param task:提交任务
     * @param call:前一次任务完成后的回调
     */
    public <Return> void post(JustReturnIt<Return> task, JustWithIt<Return> call) {
        mTaskPool.execute(() -> {
            Return result = task.onWith();
            call.onWith(result);
        });
    }
}
